package com.yang.producer;

import com.yang.message.Demo08Message;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @ClassName Demo08Producer
 * @Description: 本小节，我们还是基于RabbitMQ的<死信队列>，实现<定时消息>的功能。
 *               RabbitMQ提供了过期时间 TTL 机制，可以设置消息在队列中的存活时长。
 *               在消息到达过期时间时，会从当前队列中删除，并被RabbitMQ自动转发到对应的死信队列中。
 *               那么，如果我们创建消费者Consumer，来消费该死信队列，就可以实现<延迟队列>的效果。
 *               如果，我们便实现了定时消息的功能。
 *
 *               RabbitMQ 目前提供了 RabbitMQ Delayed Message Plugin 插件，提供更加通用的定时消息的功能。
 *               推荐直接使用RabbitMQ Delayed Message Plugin 插件
 * @Author yjl
 * @Date 2021/9/18
 * @Version V1.0
 */
@Component
public class Demo08Producer {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 如果传递了方法参数delay，则我们会设置消息的 TTL 过期时间
     * @param id
     * @param delay
     */
    public void syncSend(Integer id, Integer delay) {
        // 创建 Demo08Message 消息
        Demo08Message message = new Demo08Message();
        message.setId(id);
        // 同步发送消息
        rabbitTemplate.convertAndSend(Demo08Message.EXCHANGE, Demo08Message.ROUTING_KEY, message, new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                // 设置消息的 TTL 过期时间
                if (delay != null && delay > 0) {
                    // Spring-AMQP API 设计有问题，所以传入了 String
                    message.getMessageProperties().setExpiration(String.valueOf(delay));
                }
                return message;
            }
        });
    }
}
